package com.blog.common.redis.service;

import org.springframework.data.redis.core.ZSetOperations;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * spring redis 工具实现类
 * </p>
 *
 * @author Valerie
 * @date 2023/2/25
 **/
@SuppressWarnings("unused")
public interface RedisService {
    /**
     * 删除单个key
     *
     * @param key 键
     * @return Boolean
     */
    Boolean del(final String key);

    /**
     * 是否包括key
     *
     * @param key 键
     * @return {@link Boolean}
     */
    Boolean hasKey(final String key);

    /**
     * 删除多个key
     *
     * @param keys 键
     * @return Long
     */
    Long del(final String... keys);

    /**
     * 删除多个key
     *
     * @param keyList 键
     * @return Long
     */
    Long del(final Collection<String> keyList);


    /**
     * 删除多个key
     *
     * @param key 键
     * @return Long
     */
    Set<String> keys(final String key);

    /**
     * 设置过期时间
     *
     * @param key     键
     * @param timeout 时间秒
     * @return Long
     */
    Boolean expire(final String key, final Long timeout);

    /**
     * 设置过期时间
     *
     * @param key     键
     * @param timeout 时间
     * @param unit    时间单位
     * @return Long
     */
    Boolean expire(final String key, final Long timeout, final TimeUnit unit);


    /**
     * 设置过期时间
     *
     * @param key 键
     * @return Long
     */
    Boolean exists(final String key);


    /**
     * 返回key的过期时间
     *
     * @param key 键
     * @return Long
     */
    Long persist(final String key);


    /**
     * 返回key的过期时间
     *
     * @param key  键
     * @param unit 时间单位
     * @return Long
     */
    Long persist(final String key, TimeUnit unit);

    /* for object*/

    /**
     * 获取类型
     *
     * @param key 键
     * @param clazz 类型
     * @return {@link T}
     */

    <T> T get(final String key, Class<T> clazz);

    /* for string*/

    /**
     * 获取key
     *
     * @param key 键
     * @return Long
     */
    Object get(final String key);

    /**
     * 设置key
     *
     * @param key 键
     */
    void set(final String key, final Object value);

    /**
     * 设置key
     *
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     * @param unit    时间单位
     */
    void set(final String key, final Object value, final Long timeout, TimeUnit unit);

    /**
     * key自增1
     *
     * @param key 键
     * @return Long
     */
    Long incr(final String key);

    /**
     * key自增
     *
     * @param key   键
     * @param delta 值
     * @return Long
     */
    Long incr(final String key, final Long delta);

    /**
     * key自增
     *
     * @param key   键
     * @param delta 值
     * @return Double
     */
    Double incr(final String key, final Double delta);

    /**
     * 获取value的长度
     *
     * @param key 键
     * @return Long 长度
     */
    Long strlen(final String key);

    /* for Hash */

    /**
     * 获取Map中的val
     *
     * @param key 键
     * @return Map<Object, Object>
     */
    Object hGet(final String key, final Object hashKey);

    /**
     * 获取Map中的val
     *
     * @param key 键
     * @param hashKey 键
     * @param clazz 值
     * @return {@link T}
     */
    <T> T hGet(final String key, final Object hashKey, Class<T> clazz);

    /**
     * 获取Map
     *
     * @param key 键
     * @return Map<Object, Object>
     */
    Map<Object, Object> hGetAll(final String key);

    /**
     * 获取Map
     *
     * @param key 键
     * @return Map<Object, Object>
     */
    <K, V> Map<K, V> hGetAll(final String key, Class<K> keyClass, Class<V> valClass);

    /**
     * 向map中put val
     *
     * @param key     键
     * @param hashKey map key
     * @param value   map value
     */
    void hPut(final String key, final Object hashKey, final Object value);

    /**
     * 向map中put Map
     *
     * @param key 键
     * @param map map
     */
    void hPutAll(final String key, final Map<?, ?> map);

    /**
     * 增加map中val的值
     *
     * @param key     键
     * @param hashKey 值
     * @param delta   分数
     * @return Double  返回值
     */
    Double hIncr(final String key, final Object hashKey, final Double delta);

    /**
     * 增加map中val的值
     *
     * @param key     键
     * @param hashKey 值
     * @param delta   分数
     * @return Long 返回值
     */
    Long hIncr(final String key, final Object hashKey, final Long delta);

    /**
     * 减少map中val的值
     *
     * @param key     键
     * @param hashKey 值
     * @param delta   分数
     * @return Double  返回值
     */
    Double hDecr(final String key, final Object hashKey, final Double delta);

    /**
     * 减少map中val的值
     *
     * @param key     键
     * @param hashKey 值
     * @param delta   分数
     * @return Long 返回值
     */
    Long hDecr(final String key, final Object hashKey, final Long delta);

    /**
     * 获取map的长度
     *
     * @param key 键
     * @return Long     长度
     */
    Long hSize(final String key);

    /**
     * 判断map中是否存在key
     *
     * @param key     key
     * @param hashKey map key
     * @return Boolean
     */
    Boolean hHasKey(final String key, final Object hashKey);

    /**
     * 获取map中的所有value
     *
     * @param key key
     * @return List<Object> 返回values
     */
    List<Object> hGetValues(final String key);

    /**
     * 获取map中的所有value
     *
     * @param key key
     * @return List<Object> 返回values
     */
    <T> List<T> hGetValues(final String key, Class<T> clazz);

    /**
     * 获取map中的所有key
     *
     * @param key key
     * @return List<Object> 返回values
     */
    <T> Set<T> hGetKeys(final String key, Class<T> clazz);

    /**
     * 获取map中的所有key
     *
     * @param key key
     * @return List<Object> 返回values
     */
    Set<Object> hGetKeys(final String key);

    /* for set */

    /**
     * 向set中添加val
     *
     * @param key 键
     * @param val 值
     * @return Long val长度
     */
    Long sAdd(final String key, final Object val);


    /**
     * 向set中添加多个val
     *
     * @param key 键
     * @param val 值
     * @return Long val长度
     */
    Long sAdd(final String key, final Object... val);


    /**
     * 向set中删除多个val
     *
     * @param key 键
     * @param val 值
     * @return Long val长度
     */
    Long sRemove(final String key, final Object... val);


    /**
     * 获取set长度
     *
     * @param key 键
     * @return Long val长度
     */
    Long sSize(final String key);

    /**
     * 判断set中key是否存在
     *
     * @param key 键
     * @param val 值
     * @return Boolean 是否存在
     */
    Boolean sIsMember(final String key, final Object val);

    /**
     * 判断set中key是否存在
     *
     * @param key 键
     * @return Map<Object, Boolean> 是否存在
     */
    Map<Object, Boolean> sIsMember(final String key, final Object... val);

    /**
     * 获取set中所有元素
     *
     * @param key 键
     * @return Long val长度
     */
    Set<Object> sMembers(final String key);

    /**
     * 获取set中所有元素
     *
     * @param key 键
     * @return Long val长度
     */
    <T> Set<T> sMembers(final String key, Class<T> clazz);

    /**
     * 向zSet中添加元素
     *
     * @param key   键
     * @param val   值
     * @param score 分数
     * @return Boolean 返回是否添加成功
     */
    Boolean zAdd(final String key, final Object val, final Double score);

    /**
     * 向zSet中添加元素， 失败退出
     *
     * @param key   键
     * @param val   值
     * @param score 分数
     * @return Boolean
     */
    Boolean zAddIfAbsent(final String key, final Object val, Double score);

    /**
     * 向zSet中批量添加
     *
     * @param key    键
     * @param tuples 值
     * @return Long    长度
     */
    Long zAdd(final String key, Set<ZSetOperations.TypedTuple<Object>> tuples);

    /**
     * 返回zSet长度
     *
     * @param key 键
     * @return Long  长度
     */
    Long zCard(final String key);

    /**
     * 返回val的分数
     *
     * @param key 键
     * @param val 值
     * @return Double 分数
     */
    Double zScore(final String key, final Object val);

    /**
     * 返回多个分数
     *
     * @param key 键
     * @param val 值
     * @return List<Double>  分数列表
     */
    List<Double> zScore(final String key, final Object... val);

    /**
     * 返回多个分数
     *
     * @param key 键
     * @return List<Double>  分数列表
     */
    Map<Object, Double> zGetAll(final String key);

    /**
     * 移除zSet中的元素
     *
     * @param key 键
     * @param val 值
     * @return Long   长度
     */
    Long zRemove(final String key, final Object... val);

    /**
     * 返回分数区间内的长度
     *
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return Long     长度
     */
    Long zCount(final String key, final Double min, final Double max);

    /**
     * 增加zSet中元素的分数
     *
     * @param key   键
     * @param val   值
     * @param score 分数
     * @return Double  返回分数
     */
    Double zIncrement(final String key, final Object val, final Double score);

    /**
     * 增加zSet中元素的分数
     *
     * @param key   键
     * @param val   值
     * @param score 分数
     * @return Double  返回分数
     */
    Double zDecrement(final String key, final Object val, final Double score);

    /* for List */

    /**
     * 向list左侧插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long 长度
     */
    Long lPush(final String key, final Object val);

    /**
     * 向list中pivot左侧插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long 长度
     */
    Long lPush(final String key, final Object pivot, final Object val);

    /**
     * 向list左侧批量插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long  长度
     */
    Long lPushAll(final String key, final Object... val);

    /**
     * 向list左侧批量插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long  长度
     */
    Long lPushAll(final String key, final Collection<?> val);

    /**
     * 从list左侧弹出元素
     *
     * @param key 键
     * @return Long  长度
     */
    Object lPop(final String key);

    /**
     * 从list左侧弹出元素
     *
     * @param key 键
     * @return Long  长度
     */
    <T> T lPop(final String key, Class<T> clazz);

    /**
     * 从list左侧弹出多个元素
     *
     * @param key   键
     * @param count 个数
     * @return List<Object>    元素列表
     */
    List<Object> lPop(final String key, final long count);

    /**
     * 从list左侧弹出多个元素
     *
     * @param key   键
     * @param count 个数
     * @return List<Object>    元素列表
     */
    <T> List<T> lPop(final String key, final long count, Class<T> clazz);

    /**
     * 从list左侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @return Object
     */
    Object blPop(final String key, final long timeout);

    /**
     * 从list左侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @return Object
     */
    <T> T blPop(final String key, final long timeout, Class<T> clazz);

    /**
     * 从list左侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @param unit    单位
     * @return Object   元素
     */
    Object blPop(final String key, final long timeout, final TimeUnit unit);

    /**
     * 从list左侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @param unit    单位
     * @return Object   元素
     */
    <T> T blPop(final String key, final long timeout, final TimeUnit unit, Class<T> clazz);

    /**
     * 获取元素最后出现的位置
     *
     * @param key 键
     * @param val 值
     * @return Long  位置
     */
    Long lastIndexOf(final String key, final Object val);

    /**
     * 获取元素第一次出现的位置
     *
     * @param key 键
     * @param val 值
     * @return Long  位置
     */
    Long indexOf(final String key, final Object val);

    /**
     * 向list左侧插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long 长度
     */
    Long rPush(final String key, final Object val);

    /**
     * 向list中pivot左侧插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long 长度
     */
    Long rPush(final String key, final Object pivot, final Object val);

    /**
     * 向list左侧批量插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long  长度
     */
    Long rPushAll(final String key, final Object... val);

    /**
     * 向list左侧批量插入元素
     *
     * @param key 键
     * @param val 值
     * @return Long  长度
     */
    Long rPushAll(final String key, final Collection<?> val);

    /**
     * 从list左侧弹出元素
     *
     * @param key 键
     * @return Long  长度
     */
    Object rPop(final String key);

    /**
     * 从list右侧弹出元素
     *
     * @param key 键
     * @return Long  长度
     */
    <T> T rPop(final String key, Class<T> clazz);

    /**
     * 从list右侧弹出多个元素
     *
     * @param key   键
     * @param count 个数
     * @return List<Object>    元素列表
     */
    <T> List<T> rPop(final String key, final long count, Class<T> clazz);

    /**
     * 从list右侧弹出多个元素
     *
     * @param key   键
     * @param count 个数
     * @return List<Object>    元素列表
     */
    List<Object> rPop(final String key, final long count);

    /**
     * 从list右侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @return Object
     */
    Object brPop(final String key, final long timeout, final TimeUnit unit);

    /**
     * 从list右侧弹出元素并阻塞， 超时返回
     *
     * @param key     键
     * @param timeout 超时时间
     * @return Object
     */
    <T> T brPop(final String key, final long timeout, final TimeUnit unit, Class<T> clazz);
}
